Unik pameti v TClientDataSet (libmidas) v Kylix

Otázka od: Slezak Jan

7. 11. 2003 13:55

Omlouvam se pokud se zde toto tema jiz resilo, ale zadny takovy prispevek
jsem nenasel.

Mam nasledujici problem: pouzivam na linuxu TClientDataSet jako lokalni
databazi, v rezimu kdy ji casto oteviram a zaviram, pripadne vymenuji cds
soubor nad kterym operuje. V tomto rezimu dochazi k postupnemu a totalnimu
spotrebovani veskere dostupne pameti az do zamrznuti celeho systemu.

Uvitam jakoukoliv radu, jak problem odstranit, ale take jen zpravu, ze nize
uvedena dema nekomu z Vas funguji bez uniku pameti. Problem je pro me
naprosto fatalni, protoze nelze nijak obejit, jde o serverovou aplikaci a
protoze z duvodu portability kodu na Win32 nelze TClientDataSet nahradit.

S pozdravem

Jan Slezak
ELCOM-IPC spol. s r. o.


Problem lze demonstrovat na tomto kodu:

  program Project1;

  {$APPTYPE CONSOLE}

  uses
    SysUtils,
    DBClient;

  var
    ClientDataSet1: TClientDataSet;

  begin
    ClientDataSet1:= TClientDataSet.Create(nil);
    ClientDataSet1.FileName:= '/home/slezak/tmp/test.cds';
    ClientDataSet1.Open;

    repeat
      ClientDataSet1.Close;
      ClientDataSet1.Open;
      Sleep(1);
    until False;
  end.


Stejny efekt ma spusteni nasledujiciho programu. Nastaveni vlastnosti Data
totiz interne take zavira a otevira TClientDataSet.

  program Project2;

  {$APPTYPE CONSOLE}

  uses
    SysUtils,
    DBClient;

  var
    ClientDataSet1: TClientDataSet;
    ClientDataSet2: TClientDataSet;

  begin
    ClientDataSet1:= TClientDataSet.Create(nil);
    ClientDataSet2:= TClientDataSet.Create(nil);

    ClientDataSet1.FileName:= '/home/slezak/tmp/test.cds';
    ClientDataSet1.Open;

    repeat
      ClientDataSet2.Data:= ClientDataSet1.Data;
      Sleep(1);
    until False;
  end.


Postupnym rozborem zdrojoveho kodu TClientDataSetu jsem dospel k zaveru, ze
problem zpusobuje primo knihovna libmidas.so.1.0. Lze to demonstrovat timto
kodem:

  program Project3;

  {$APPTYPE CONSOLE}

  uses
    Classes,
    SysUtils,
    VarUtils,
    DSIntf;

  var
    Stream: TFileStream;
    Size: Integer;
    VarBound: TVarArrayBoundArray;
    DataPtr: Pointer;
    DataPacket: TDataPacket;
    DSBase: IDSBase;

  begin
    Stream:= TFileStream.Create('/home/slezak/tmp/test.cds', fmOpenRead);
    try
      Size:= Stream.Size;
      FillChar(VarBound, SizeOf(VarBound), 0);
      VarBound[0].ElementCount:= Size;
      DataPacket:= TDataPacket(SafeArrayCreate(varByte, 1, VarBound));
      SafeArrayAccessData(DataPacket, DataPtr);
      try
        Stream.Read(DataPtr^, Size);
      finally
        SafeArrayUnAccessData(DataPacket);
      end;
    finally
      Stream.Free;
    end;

    repeat
      CreateDbClientObject(CLSID_DSBase, IDSBase, DSBase);
      DSBase.AppendData(DataPacket, True);
      DSBase:= nil; // nebo take DSBase._Release;
      Sleep(1);
    until False;
  end.





----------
* www.inMail.sk - Vasa emailova adresa na cely zivot ZDARMA
* Mail neobsahuje virusy. Zkontrolovane antivirusom NOD32 (www.eset.sk)
* www.SlovakNET.sk - profesionalny webhosting, domena .SK ZADARMO
* Zoner Media Explorer 5 - stiahnite si pomocnika pre digitalnu fotografiu
(zme.zoner.sk)